package com.rem.designPattern.designPrinciple.dependenceInversion.improve;

/**
 * 设计模式七大原则--依赖倒转
 * 抽象不应该依赖细节，细节应该依赖抽象，中心思想是面向接口编程
 * <p>
 * 需求：一个人接收不同的消息
 * <p>
 * 改进：创建一个接口，人只需要依赖接口即可，消息实现不同的内容
 * <p>
 * 依赖关系有三种传递方式：接口依赖、 set注入、 构造器传递
 *
 * @author Rem
 * @date 2022-11-12
 */
public class DependecyInversion02 {
    public static void main(String[] args) {
        Receiver email = new Email();
        Receiver wechat = new Wechat();

        System.out.println("---------接口依赖------------");
        Person person = new Person();
        person.receive(email);
        person.receive(wechat);

        System.out.println("---------set注入------------");
        Person2 person2a = new Person2();
        person2a.setReceiver(email);
        person2a.receive();
        Person2 person2b = new Person2();
        person2b.setReceiver(wechat);
        person2b.receive();

        System.out.println("---------构造器传递------------");
        Person3 person3a = new Person3(email);
        person3a.receive();
        Person3 person3b = new Person3(email);
        person3b.receive();
    }
}

/**
 * 通过接口依赖传递
 */
class Person {
    public void receive(Receiver receiver) {
        System.out.println(receiver.getInfo());
    }
}

/**
 * 通过set注入传递依赖
 */
class Person2 {
    Receiver receiver;

    public void setReceiver(Receiver receiver) {
        this.receiver = receiver;
    }

    public void receive() {
        System.out.println(this.receiver.getInfo());
    }
}

/**
 * 通过构造器传递依赖
 */
class Person3 {
    Receiver receiver;

    public Person3(Receiver receiver) {
        this.receiver = receiver;
    }

    public void receive() {
        System.out.println(this.receiver.getInfo());
    }
}

interface Receiver {

    String getInfo();
}

class Email implements Receiver {

    @Override
    public String getInfo() {
        return "电子邮件信息: hello,world";
    }
}

class Wechat implements Receiver {

    @Override
    public String getInfo() {
        return "微信消息: hi,chat";
    }
}
